<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of G_Application
 *
 * @author kouhongfei
 */
class G_Application {

    const WEB_APP = 1;
    const CLI_APP = 2;

    public static function init($type) {
        if ($type == self::WEB_APP) {
            include G_ROOT . "Application" . DS . "G_WebApp.cls.php";
            return new G_WebApp;
        } elseif ($type == self::CLI_APP) {
            include G_ROOT . "Application" . DS . "G_CliApp.cls.php";
            return new G_CliApp;
        } else {
            echo "程序配置错误";
            die();
        }
    }

}

abstract class GC_Application {

    protected $_Controller;
    protected $_Action;
    protected $_FileExt;
    private $_AppConfigPath;
    private $_AppEnv = 'dev';
    public $_config;

    public function setOption($data) {
        if (isset($data['config'])) {
            $this->_AppConfigPath = $data['config'];
        } else {
            $this->_AppConfigPath = 'config' . DS . 'config.ini';
        }
        if (isset($data['config_env'])) {
            $this->_AppEnv = $data['config_env'];
        }
        return $this;
    }

    public function run($url) {
        spl_autoload_register(array($this, 'autoloadClass'));
        $this->loadConfig();
        $this->parseUrl($url);
        $Controller = $this->_Controller . "Controller";
        include_once G_APPDIR . 'controllers' . DS . $this->_Controller . '.php';
        $_cls = new $Controller($this);
        $_cls->{$this->_Action}();
    }

    public function autoloadClass($cls) {
        $clsFile = preg_replace("/Model$/", "", $cls);
        $clsPath = G_APPDIR . 'models' . DS . $clsFile . '.php';
        if (file_exists($clsPath)) {
            include_once $clsPath;
        }
    }

    /**
     * 分析URL数据
     */
    protected function parseUrl($url) {
        if (strpos($url, '?') !== false) {
            $tmp = explode('?', $url);
            $url = $tmp[0];
        }
        $ext = substr(strrchr($url, '.'), 0);
        $url = str_replace($ext, '', $url);
        $this->_FileExt = preg_replace("/^\./", "", $ext);
        $url = preg_replace("/^(\/)+/", '', $url);
        $urls = explode('/', $url);
        $this->urlMap($urls);
    }

    /**
     * 加载配置文件
     */
    protected function loadConfig() {
        G_Config::init("ini://" . G_APPDIR . $this->_AppConfigPath);
        //var_dump(G_Config::getItem('db'));
    }

    /**
     * 处理url的路由
     * @param type $url
     */
    protected function urlMap($url) {
        $this->_Controller = ucfirst($url[0] ? $url[0] : 'index');
        $this->_Action = isset($url[1]) ? $url[1] : "index";
    }

    public function getController() {
        return $this->_Controller;
    }

    public function getAction() {
        return $this->_Action;
    }

    public function getSuffixes() {
        return $this->_FileExt;
    }

}

/**
 * 控制器
 */
class G_Controller {

    protected $_app;
    protected $_vars = array();

    public function __construct($App) {
        $this->_app = $App;
    }

    protected function assign($k, $v) {
        $this->_vars[$k] = $v;
    }

    public function __call($name, $arguments) {
        //@todo 方法存在;
    }

    private function _input($k, $data) {
        $rs = "";
        if (isset($data[$k])) {
            if (is_array($data[$k])) {
                $rs = array();
                foreach ($data[$k] AS $key => $v) {
                    $rs[$key] = $this->_input($key, $data[$k]);
                }
            } else {
                if (get_magic_quotes_gpc()) {
                    $rs = stripslashes($data[$k]);
                } else {
                    $rs = $data[$k];
                }
            }
        }
        return $rs;
    }

    protected function _get($key) {
        return $this->_input($key, $_GET);
    }

    protected function _arg($key) {
        static $_Ars = false;
        if ($_Ars === false) {
            $_Ars = array();
            foreach ($_SERVER['argv'] AS $item) {
                $index = strpos($item, "=");
                if ($index !== false) {
                    $_Ars[substr($item, 0, $index)] = substr($item, $index + 1);
                }
            }
        }
        if (isset($_Ars[$key])) {
            return $_Ars[$key];
        }
        return null;
    }

    protected function _post($key) {
        return $this->_input($key, $_POST);
    }

    protected function _session($k, $v = null) {
        if ($v) {
            $_SESSION[$k] = $v;
        } else {
            return $this->_input($k, $_SESSION);
        }
    }

    protected function _cookie($k, $v = null, $time = 3600, $path = "/", $domain = "") {
        if ($v) {
            setcookie($k, $v, time() + $time, $path, $domain);
        }
        return $this->_input($k, $_COOKIE);
    }

    /**
     * 获取Resuest的请求数据
     * @param type $k
     * @return type
     */
    protected function _request($k) {
        return $this->_input($k, $_REQUEST);
    }

    /**
     * 是不是POST提交
     * @return type
     */
    protected function _isPost() {
        return $_SERVER['REQUEST_METHOD'] == "POST";
    }

    /**
     * 判断是否是Ajax提交
     * @return type
     */
    protected function _isAjax() {
        return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
    }

    /**
     * 获取客户端IP
     * @return type
     */
    protected function _ip() {
        $cip = '';
        if (!empty($_SERVER["HTTP_CLIENT_IP"])) {
            $cip = $_SERVER["HTTP_CLIENT_IP"];
        } elseif (!empty($_SERVER["HTTP_X_FORWARDED_FOR"])) {
            $cip = $_SERVER["HTTP_X_FORWARDED_FOR"];
        } elseif (!empty($_SERVER["REMOTE_ADDR"])) {
            $cip = $_SERVER["REMOTE_ADDR"];
        }
        return $cip;
    }

    protected function fetch($tpl = "") {
        if (!$tpl) {
            $tpl = strtolower($this->_app->getController()) . DS . strtolower($this->_app->getAction());
        }
        $tpl = G_APPDIR . "templates" . DS . $tpl . '.htm';
        extract($this->_vars);
        ob_start();
        include $tpl;
        $content = ob_get_contents();
        ob_clean();
        return $content;
    }

    protected function display($tpl = "") {
        echo $this->fetch($tpl);
    }

}

/**
 * Model层的类
 */
class G_Model {

    private $_table;
    private $_tableprefix = "";
    private $_db;

    public function __construct($table = null, $prefix = null, $config = null) {
        if ($config) {
            $this->_db = G_Db::init($config);
        } else {
            $this->_db = G_Db::init(G_Config::getItem('db'));
        }
        if ($table) {
            $this->_table = $table;
        } else {
            $cls = get_called_class();
            $cls = preg_replace("/Model$/", '', $cls);
            $this->_table = strtolower($cls);
        }
        //var_dump(G_Config::getItem('db.tableprefix'));
        if ($prefix) {
            $this->_tableprefix = $prefix;
        } else {
            $prefix = G_Config::getItem('db.tableprefix');
            if ($prefix) {
                $this->_tableprefix = $prefix;
            }
        }
    }

    /**
     * 插入数据
     * @param type $data
     * @param type $tablename
     * @return type
     */
    public function insert($data, $tablename = null) {
        foreach ($data AS $k => $v) {
            $data[$k] = $this->_db->escape($v);
        }
        $SQL = sprintf("INSERT INTO %s(`%s`) VALUES('%s')", $this->table($tablename), implode("`,`", array_keys($data)), implode("','", array_values($data)));
        //echo $SQL;
        return $this->_db->insert($SQL);
    }

    /**
     * 更新数据
     * @param type $data
     * @param type $where
     * @param type $tablename
     * @return type
     */
    public function update($data, $where = null, $tablename = null) {
        $rs = array();
        foreach ($data AS $k => $v) {
            $rs = sprintf("`%s`='%'", $k, $this->_db->escape($v));
        }
        $SQL = sprintf("UPDATE %s SET %s %s", $this->table($tablename), implode(",", $rs), $this->where($where));
        return $this->_db->update($SQL);
    }

    /**
     * 删除初级
     * @param type $where
     * @param type $tablename
     * @return type
     */
    public function delete($where = null, $tablename = null) {
        $SQL = sprintf("DELETE FROM %s %s", $this->table($tablename), $this->where($where));
        return $this->_db->delete($SQL);
    }

    public function createTable() {
        
    }

    public function begin() {
        return $this->_db->begin();
    }

    public function commit() {
        return $this->_db->commit();
    }

    public function rollback() {
        return $this->_db->rollback();
    }

    public function table($table = null) {
        if ($table) {
            return $table;
        }//var_dump($this->_tableprefix . $this->_table);
        return $this->_tableprefix . $this->_table;
    }

    public function where($where = null) {
        if ($where) {
            if (is_array($where)) {
                $rs = array();
                $ks = array('<', '>', '=');
                foreach ($where AS $k => $v) {
                    if (in_array(substr($k, -1), $ks)) {
                        $rs[] = sprintf("%s'%s'", $k, $this->_db->escape($v));
                    } elseif (in_array(substr($v, 0, 1), $ks)) {
                        //$rs[] = sprintf("%s'%s'",$k,$this->_db->escape($v));
                    } else {
                        $rs[] = sprintf("`%s`='%s'", $k, $this->_db->escape($v));
                    }
                }
                return sprintf(" WHERE %s", implode(" AND ", $rs));
            } else {
                return sprintf(" WHERE %s", $where);
            }
        }
        return "";
    }

    public function order($order = null) {
        if (is_array($order)) {
            return sprintf("ORDER BY %s", implode(',', $order));
        } elseif (is_string($order)) {
            return " ORDER BY " . $order;
        }
        return "";
    }

    public function getRow($where = null, $order = null) {
        return $this->_db->getRow(sprintf("SELECT * FROM %s %s %s LIMIT 1", $this->table(), $this->where($where), $this->order($order)));
    }

    public function getVal($filde, $where = null, $order = null) {
        return $this->_db->getVal(sprintf("SELECT %s FROM %s %s %s LIMIT 1", $filde, $this->table(), $this->where($where), $this->order($order)));
    }

}

?>
